package com.yc.cloud.openai.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.yc.cloud.basic.exception.Asserts;
import com.yc.cloud.openai.dto.IATResultDTO;
import com.yc.cloud.openai.dto.resp.XFNLPApiResp;
import com.yc.cloud.openai.request.IatParam;
import com.yc.cloud.openai.service.IATService;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service("XFIatServiceImpl")
public class XFIatServiceImpl implements IATService {


    private static final String URL = "http://openapi.xfyun.cn/v2/aiui";

    //191****3095 这个账号下的内容
    private static final String APPID = "8bb87ebd";
    private static final String API_KEY = "a040ea63c183da81a81ea405294a2153";
    private static final String DATA_TYPE = "audio";
    //iat专门使用该场景
    private static final String SCENE = "main-iat_box";
    private static final String SAMPLE_RATE = "16000";
    private static final String AUTH_ID = "2894c985bf8b1111c6728db79d3479ae";
    private static final String AUE = "raw";
    private static final String SUCCESS_CODE = "0";
    private final String SUB_IAT = "iat";

    @Override
    public IATResultDTO getIatResult(IatParam param) {
        val startTime = System.currentTimeMillis();
        val header = buildHeader(param.getAppKey(), param.getAppid());
        String result = httpPost(header, FileUtil.readBytes(param.getContent()));
        //log.debug("XFNLPApiServiceImpl getNLPResult---->{}", result);
        if (StrUtil.isEmpty(result)) {
            return null;
        }
        log.info("XFIatServiceImpl getIatResult---->{}", result);
        val xfnlpApiResp = JSONUtil.toBean(result, XFNLPApiResp.class);
        //响应失败
        if (!SUCCESS_CODE.equals(xfnlpApiResp.getCode())) {
            log.error("XFIatServiceImpl ERROR--->{}", xfnlpApiResp.getDesc());
            Asserts.fail(xfnlpApiResp.getDesc());
        }
        val ttsResultDTO = new IATResultDTO();
        val dataDTOList = xfnlpApiResp.getData();
        dataDTOList.forEach(dataDTO -> {
            val sub = dataDTO.getSub();
            if (SUB_IAT.equals(sub)) {
                //将iat结果放入dto中
                ttsResultDTO.setResult(dataDTO.getText());
            }
        });
        val endTime = System.currentTimeMillis();
        val costTime = endTime - startTime;
        ttsResultDTO.setCostTime(costTime);
        return ttsResultDTO;
    }


    private Map<String, String> buildHeader(String appKey, String appid) {
        if (StrUtil.isEmpty(appKey)) {
            appKey = API_KEY;
        }
        if (StrUtil.isEmpty(appid)) {
            appid = APPID;
        }
        String curTime = System.currentTimeMillis() / 1000L + "";
        // 使用 HashMap 构建参数
        Map<String, String> params = new HashMap<>();
        params.put("aue", AUE);
        params.put("sample_rate", SAMPLE_RATE);
        params.put("auth_id", AUTH_ID);
        params.put("data_type", DATA_TYPE);
        params.put("scene", SCENE);
//        params.put("tts_aue", AUE);

        String param = JSONUtil.toJsonStr(params);
        String paramBase64 = new String(Base64.encodeBase64(param.getBytes(StandardCharsets.UTF_8)));
        String checkSum = org.apache.commons.codec.digest.DigestUtils.md5Hex(appKey + curTime + paramBase64);

        Map<String, String> header = new HashMap<>();
        header.put("X-Param", paramBase64);
        header.put("X-CurTime", curTime);
        header.put("X-CheckSum", checkSum);
        header.put("X-Appid", appid);
        return header;
    }


    private String httpPost(Map<String, String> header, byte[] body) {
        StringBuilder result = new StringBuilder();
        BufferedReader in = null;
        OutputStream out = null;
        try {
            java.net.URL realUrl = new URL(URL);
            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
            for (String key : header.keySet()) {
                connection.setRequestProperty(key, header.get(key));
            }
            connection.setDoOutput(true);
            connection.setDoInput(true);

            //connection.setConnectTimeout(20000);
            //connection.setReadTimeout(20000);
            try {
                out = connection.getOutputStream();
                out.write(body);
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }

            try {
                in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    result.append(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }

}
